package com.cloud.gateway.config;

import com.cloud.gateway.handler.WebErrorHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;

import java.util.Collections;
import java.util.List;

@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorConfig {

    private ServerProperties serverProperties;

    private ResourceProperties resourceProperties;

    private ServerCodecConfigurer serverCodecConfigurer;

    private List<ViewResolver> viewResolvers;

    private ApplicationContext applicationContext;

    public ErrorConfig(ResourceProperties resourceProperties,
                       ServerProperties serverProperties,
                       ServerCodecConfigurer serverCodecConfigurer,
                       ObjectProvider<List<ViewResolver>> viewResolversProvider,
                       ApplicationContext applicationContext) {
        this.resourceProperties = resourceProperties;
        this.serverProperties = serverProperties;
        this.serverCodecConfigurer = serverCodecConfigurer;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.applicationContext = applicationContext;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public WebErrorHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        WebErrorHandler errorHandler = new WebErrorHandler(errorAttributes, resourceProperties, serverProperties.getError(), applicationContext);
        errorHandler.setViewResolvers(viewResolvers);
        errorHandler.setMessageWriters(serverCodecConfigurer.getWriters());
        errorHandler.setMessageReaders(serverCodecConfigurer.getReaders());
        return errorHandler;
    }
}